﻿using System.Collections;
using System.Data;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace DoNet.Common.Extensions
{
    /// <summary>
    /// 对象自定义扩展类
    /// </summary>
    public static class ObjectExtension
    {
        /// <summary>
        /// 将object转换为string类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>string。</returns>
        public static string ObjectToString(this object obj, string defaultValue = "")
        {
            if (obj != null)
            {
                return obj.ToString() ?? "";
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将DateTime?转换为string类型信息。
        /// </summary>
        /// <param name="obj">DateTime?。</param>
        /// <param name="format">标准或自定义日期和时间格式的字符串。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>string。</returns>
        public static string DateTimeToString(this DateTime? obj, string format, string defaultValue = "")
        {
            if (obj != null)
            {
                return obj.Value.ToString(format);
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将TimeSpan?转换为string类型信息。
        /// </summary>
        /// <param name="obj">TimeSpan?。</param>
        /// <param name="format">标准或自定义时间格式的字符串。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>string。</returns>
        public static string TimeSpanToString(this TimeSpan? obj, string format, string defaultValue = "")
        {
            if (obj != null)
            {
                return obj.Value.ToString(format);
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为截取后的string类型信息。
        /// </summary>
        /// <param name="o">object。</param>
        /// <param name="startIndex">此实例中子字符串的起始字符位置（从零开始）。</param>
        /// <param name="length">子字符串中的字符数。</param>
        /// <param name="suffix">后缀。如果没有截取则不添加。</param>
        /// <returns>截取后的string类型信息。</returns>
        public static string ObjectToSubString(this object obj, int startIndex, int length, string suffix = "")
        {
            string inputString = obj.ObjectToString();
            startIndex = Math.Max(startIndex, 0);
            startIndex = Math.Min(startIndex, (inputString.Length - 1));
            length = Math.Max(length, 1);
            if (startIndex + length > inputString.Length)
            {
                length = inputString.Length - startIndex;
            }
            if (inputString.Length == startIndex + length)
            {
                return inputString;
            }
            else
            {
                return inputString.Substring(startIndex, length) + suffix;
            }
        }

        /// <summary>
        /// 将object转换为byte类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>byte。</returns>
        public static byte ObjectToByte(this object obj, byte defaultValue = default(byte))
        {
            if (byte.TryParse(obj.ObjectToString(), out byte result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为char类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>char。</returns>
        public static char ObjectToChar(this object obj, char defaultValue = default(char))
        {
            if (char.TryParse(obj.ObjectToString(), out char result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为int类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>int。</returns>
        public static int ObjectToInt(this object obj, int defaultValue = default(int))
        {
            if (int.TryParse(obj.ObjectToString(), out int result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }
        /// <summary>
        /// 将object转换为double类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>double。</returns>
        public static double ObjectToDouble(this object obj, double defaultValue = default(double))
        {
            if (double.TryParse(obj.ObjectToString(), out double result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为decimal类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>decimal。</returns>
        public static decimal ObjectToDecimal(this object obj, decimal defaultValue = default(decimal))
        {
            if (decimal.TryParse(obj.ObjectToString(), out decimal result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为float类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>float。</returns>
        public static float ObjectToFloat(this object obj, float defaultValue = default(float))
        {
            if (float.TryParse(obj.ObjectToString(), out float result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为long类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>long。</returns>
        public static long ObjectToLong(this object obj, long defaultValue = default(long))
        {
            if (long.TryParse(obj.ObjectToString(), out long result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为bool类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>bool。</returns>
        public static bool ObjectToBool(this object obj, bool defaultValue = default(bool))
        {
            if (bool.TryParse(obj.ObjectToString(), out bool result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为sbyte类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>sbyte。</returns>
        public static sbyte ObjectToSbyte(this object obj, sbyte defaultValue = default(sbyte))
        {
            if (sbyte.TryParse(obj.ObjectToString(), out sbyte result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为short类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>short。</returns>
        public static short ObjectToShort(this object obj, short defaultValue = default(short))
        {
            if (short.TryParse(obj.ObjectToString(), out short result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为ushort类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>ushort。</returns>
        public static ushort ObjectToUShort(this object obj, ushort defaultValue = default(ushort))
        {
            if (ushort.TryParse(obj.ObjectToString(), out ushort result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为ulong类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>ulong。</returns>
        public static ulong ObjectToULong(this object obj, ulong defaultValue = default(ulong))
        {
            if (ulong.TryParse(obj.ObjectToString(), out ulong result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为Enum[T]类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>Enum[T]。</returns>
        public static T ObjectToEnum<T>(this object obj, T defaultValue = default(T)) where T : struct
        {
            if (Enum.TryParse(obj.ObjectToString(), out T result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为DateTime类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>DateTime。</returns>
        public static DateTime ObjectToDateTime(this object obj, DateTime defaultValue = default(DateTime))
        {
            if (defaultValue == default(DateTime))
            {
                defaultValue = new DateTime(1753, 1, 1);
            }
            if (!DateTime.TryParse(obj.ObjectToString(), out DateTime result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为TimeSpan类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>TimeSpan。</returns>
        public static TimeSpan ObjectToTimeSpan(this object obj, TimeSpan defaultValue = default(TimeSpan))
        {
            if (defaultValue == default(TimeSpan))
            {
                defaultValue = new TimeSpan(0, 0, 0);
            }
            if (TimeSpan.TryParse(obj.ObjectToString(), out TimeSpan result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将object转换为Guid类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <param name="defaultValue">默认值。</param>
        /// <returns>Guid。</returns>
        public static Guid ObjectToGuid(this object obj, Guid defaultValue = default(Guid))
        {
            if (Guid.TryParse(obj.ObjectToString(), out Guid result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }
        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <typeparam name="T">转换的元素类型。</typeparam>
        /// <param name="list">集合。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>数据集。</returns>
        public static DataSet ToDataSet<T>(this IEnumerable<T> list, bool generic = true)
        {
            return ListToDataSet(list, generic);
        }

        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <param name="list">集合。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>数据集。</returns>
        public static DataSet ToDataSet(this IEnumerable list, bool generic = true)
        {
            return ListToDataSet(list, generic);
        }

        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <typeparam name="T">转换的元素类型。</typeparam>
        /// <param name="list">集合。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>数据集。</returns>
        public static DataSet ToDataSet<T>(this IEnumerable list, bool generic = true)
        {
            return ListToDataSet(list, typeof(T), generic);
        }

        /// <summary>
        /// 将实例转换为集合数据集。
        /// </summary>
        /// <typeparam name="T">实例类型。</typeparam>
        /// <param name="o">实例。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>数据集。</returns>
        public static DataSet ToListSet<T>(this T obj, bool generic = true)
        {
            IEnumerable list = new T[] { obj };
            if (obj is IEnumerable)
            {
                var ienumerable = obj as IEnumerable;
                if (ienumerable != null)
                    list = ienumerable;
            }
            return ListToDataSet(list, generic);
        }

        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <param name="list">集合。</param>
        /// <param name="t">转换的元素类型。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>转换后的数据集。</returns>
        private static DataSet ListToDataSet(IEnumerable list, Type? t, bool generic)
        {
            using (DataSet ds = new DataSet("Data"))
            {
                if (t == null)
                {
                    if (list != null)
                    {
                        foreach (var i in list)
                        {
                            if (i == null)
                            {
                                continue;
                            }
                            t = i.GetType();
                            break;
                        }
                    }
                }
                if (t != null)
                {
                    ds.Tables.Add(t.Name);
                    //如果集合中元素为DataSet扩展涉及到的基本类型时，进行特殊转换。
                    if (!t.IsValueType && t != typeof(string))
                    {
                        //处理模型的字段和属性。
                        var fields = t.GetFields();
                        var properties = t.GetProperties();
                        foreach (var j in fields)
                        {
                            if (!ds.Tables[0].Columns.Contains(j.Name))
                            {
                                if (generic)
                                {
                                    ds.Tables[0].Columns.Add(j.Name, j.FieldType);
                                }
                                else
                                {
                                    ds.Tables[0].Columns.Add(j.Name);
                                }
                            }
                        }
                        foreach (var j in properties)
                        {
                            if (!ds.Tables[0].Columns.Contains(j.Name))
                            {
                                if (generic)
                                {
                                    ds.Tables[0].Columns.Add(j.Name, j.PropertyType);
                                }
                                else
                                {
                                    ds.Tables[0].Columns.Add(j.Name);
                                }
                            }
                        }
                        if (list != null)
                        {
                            //读取list中元素的值。
                            foreach (var i in list)
                            {
                                if (i == null)
                                {
                                    continue;
                                }
                                DataRow addRow = ds.Tables[0].NewRow();
                                foreach (var j in fields)
                                {
                                    MemberExpression field = Expression.Field(Expression.Constant(i), j.Name);
                                    LambdaExpression lambda = Expression.Lambda(field, new ParameterExpression[] { });
                                    Delegate func = lambda.Compile();
                                    addRow[j.Name] = func.DynamicInvoke();
                                }
                                foreach (var j in properties)
                                {
                                    MemberExpression property = Expression.Property(Expression.Constant(i), j);
                                    LambdaExpression lambda = Expression.Lambda(property, new ParameterExpression[] { });
                                    Delegate func = lambda.Compile();
                                    addRow[j.Name] = func.DynamicInvoke();
                                }
                                ds.Tables[0].Rows.Add(addRow);
                            }
                        }
                    }
                    else
                    {
                        ds.Tables[0].TableName = "Info";
                        ds.Tables[0].Columns.Add(t.Name);
                        if (list != null)
                        {
                            foreach (var i in list)
                            {
                                DataRow addRow = ds.Tables[0].NewRow();
                                addRow[t.Name] = i;
                                ds.Tables[0].Rows.Add(addRow);
                            }
                        }
                    }
                }
                return ds;
            }
        }

        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <typeparam name="T">转换的元素类型。</typeparam>
        /// <param name="list">集合。</param>
        /// <param name="generic">是否生成泛型数据集。</param>
        /// <returns>数据集。</returns>
        private static DataSet ListToDataSet<T>(IEnumerable<T> list, bool generic)
        {
            return ListToDataSet(list, typeof(T), generic);
        }

        /// <summary>
        /// 将集合转换为数据集。
        /// </summary>
        /// <param name="list">集合。</param>
        /// <param name="generic">是否转换为字符串形式。</param>
        /// <returns>转换后的数据集。</returns>
        private static DataSet ListToDataSet(IEnumerable list, bool generic)
        {
            return ListToDataSet(list, null, generic);
        }

        /// <summary>
        /// 获取DataSet第一表，第一行，第一列的值。
        /// </summary>
        /// <param name="ds">DataSet数据集。</param>
        /// <returns>值。</returns>
        public static object? GetData(this DataSet ds)
        {
            if (ds != null)
            { 
                if(ds.Tables.Count > 0)
                {
                    return ds.Tables[0].GetData();
                }
            }
            return default;
        }

        /// <summary>
        /// 获取DataTable第一行，第一列的值。
        /// </summary>
        /// <param name="dt">DataTable数据集表。</param>
        /// <returns>值。</returns>
        public static object? GetData(this DataTable dt)
        {
            if (dt.Columns.Count > 0 && dt.Rows.Count > 0)
            {
                return dt.Rows[0][0];
            }
            return default;
        }

        /// <summary>
        /// 获取DataSet第一个匹配columnName的值。
        /// </summary>
        /// <param name="ds">数据集。</param>
        /// <param name="columnName">列名。</param>
        /// <returns>值。</returns>
        public static object? GetData(this DataSet ds, string columnName)
        {
            if (ds != null)
            { 
                if(ds.Tables.Count > 0)
                {
                    foreach (DataTable dt in ds.Tables)
                    {
                        var obj = dt.GetData(columnName);
                        if (obj != null)
                        {
                            if (!string.IsNullOrEmpty(obj.ToString()))
                            {
                                return obj;
                            }
                        }
                    }
                }
            }
            return default;
        }

        /// <summary>
        /// 获取DataTable第一个匹配columnName的值。
        /// </summary>
        /// <param name="dt">数据表。</param>
        /// <param name="columnName">列名。</param>
        /// <returns>值。</returns>
        public static object? GetData(this DataTable dt, string columnName)
        {
            if (string.IsNullOrEmpty(columnName))
            {
                return GetData(dt);
            }
            else
            {
                if (dt.Columns.Count > 0 && dt.Rows.Count > 0 && dt.Columns.IndexOf(columnName) > -1)
                {
                    return dt.Rows[0][columnName];
                }
            }
            return default;
        }

        /// <summary>
        /// 从object中获取bool类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>bool。</returns>
        public static bool? GetBool(this object obj)
        {
            Regex BoolRegex = new Regex("(?<info>(true|false))", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (bool.TryParse(BoolRegex.Match(obj.ObjectToString()).Groups["info"].Value, out bool result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 从object中获取int类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>int。</returns>
        public static int? GetInt(this object obj)
        {
            Regex IntRegex = new Regex("(?<info>-?\\d+)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (int.TryParse(IntRegex.Match(obj.ObjectToString()).Groups["info"].Value, out int result))
            {
                return result;
            }
            return null;
        }

        private static Regex DecimalRegex = new Regex("(?<info>-?\\d+(\\.\\d+)?)", RegexOptions.IgnoreCase | RegexOptions.Singleline);

        /// <summary>
        /// 从object中获取decimal类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>decimal。</returns>
        public static decimal? GetDecimal(this object obj)
        {
            if (decimal.TryParse(DecimalRegex.Match(obj.ObjectToString()).Groups["info"].Value, out decimal result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 从object中获取double类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>double。</returns>
        public static double? GetDouble(this object obj)
        {
            if (double.TryParse(DecimalRegex.Match(obj.ObjectToString()).Groups["info"].Value, out double result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 从object中获取正数信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>decimal。</returns>
        public static decimal? GetPositiveNumber(this object obj)
        {
            if (decimal.TryParse(DecimalRegex.Match(obj.ObjectToString()).Groups["info"].Value, out decimal result))
            {
                return Math.Abs(result);
            }
            return null;
        }

        /// <summary>
        /// 从object中获取DateTime?类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>DateTime?。</returns>
        public static DateTime? GetDateTime(this object obj)
        {
            Regex DateTimeRegex = new Regex("(?<info>(((\\d+)[/年-](0?[13578]|1[02])[/月-](3[01]|[12]\\d|0?\\d)[日]?)|((\\d+)[/年-](0?[469]|11)[/月-](30|[12]\\d|0?\\d)[日]?)|((\\d+)[/年-]0?2[/月-](2[0-8]|1\\d|0?\\d)[日]?))(\\s((2[0-3]|[0-1]\\d)):[0-5]\\d:[0-5]\\d)?)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (DateTime.TryParse(DateTimeRegex.Match(obj.ObjectToString()).Groups["info"].Value.Replace("年", "-").Replace("月", "-").Replace("/", "-").Replace("日", ""), out DateTime result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 从object中获取TimeSpan?类型信息。
        /// </summary>
        /// <param name="o">object。</param>
        /// <returns>TimeSpan?。</returns>
        public static TimeSpan? GetTimeSpan(this object obj)
        {
            Regex TimeSpanRegex = new Regex("(?<info>-?(\\d+\\.(([0-1]\\d)|(2[0-3])):[0-5]\\d:[0-5]\\d)|((([0-1]\\d)|(2[0-3])):[0-5]\\d:[0-5]\\d)|(\\d+))", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (TimeSpan.TryParse(TimeSpanRegex.Match(obj.ObjectToString()).Groups["info"].Value, out TimeSpan result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 从object中获取Guid?类型信息。
        /// </summary>
        /// <param name="obj">object。</param>
        /// <returns>Guid?。</returns>
        public static Guid? GetGuid(this object obj)
        {
            Regex GuidRegex = new Regex("(?<info>\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (Guid.TryParse(GuidRegex.Match(obj.ObjectToString()).Groups["info"].Value, out Guid result))
            {
                return result;
            }
            return null;
        }

        /// <summary>
        /// 删除html标签。
        /// </summary>
        /// <param name="html">输入的字符串。</param>
        /// <returns>没有html标签的字符串。</returns>
        public static string RemoveHtmlTags(this string html)
        {
            return Regex.Replace(Regex.Replace(Regex.Replace((html ?? string.Empty).Replace("&nbsp;", " ").Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " ").Replace("\t", " "), "<\\/?[^>]+>", "\r\n"), "(\r\n)+", "\r\n"), "(\\s)+", " ").Trim();
        }

        /// <summary>
        /// 字符串转换为文件名。
        /// </summary>
        /// <param name="s">字符串。</param>
        /// <returns>文件名。</returns>
        public static string ToFileName(this string s)
        {
            return Regex.Replace(s.ObjectToString(), @"[\\/:*?<>|]", "_").Replace("\t", " ").Replace("\r\n", " ").Replace("\"", " ");
        }

        /// <summary>
        /// 对 URL 字符串进行编码。
        /// </summary>
        /// <param name="s">要编码的文本。</param>
        /// <param name="regex">匹配要编码的文本。</param>
        /// <param name="encoding">指定编码方案的 System.Text.Encoding 对象。</param>
        /// <returns>一个已编码的字符串。</returns>
        public static string ToUrlEncodeString(this string s, Regex? regex = default(Regex), Encoding? encoding = null)
        {
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            if (regex != null)
            {
                List<string> l = new List<string>();
                foreach (char i in s)
                {
                    string t = i.ToString();
                    l.Add(regex.IsMatch(t) ? HttpUtility.UrlEncode(t, encoding) : t);
                }
                return string.Join(string.Empty, l);
            }
            else
            {
                return HttpUtility.UrlEncode(s, encoding);
            }
        }

        /// <summary>
        /// 对 URL 字符串进行编码。
        /// </summary>
        /// <param name="s">要编码的文本。</param>
        /// <param name="regex">匹配要编码的文本。</param>
        /// <param name="encoding">指定编码方案的 System.Text.Encoding 对象。</param>
        /// <returns>一个已编码的字符串。</returns>
        public static string ToUrlEncodeString(this string s, string regex, Encoding? encoding = null)
        {
            return ToUrlEncodeString(s, new Regex(regex), encoding);
        }

        /// <summary>
        /// 判断当前字符串是否是移动电话号码
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static bool IsMobile(this string mobile)
        {
            return new Regex("^1[3|4|5|7|8][0-9]\\d{4,8}$").IsMatch(mobile);
        }

        /// <summary>
        /// 判断当前字符串是否为邮箱
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static bool IsEmail(this string email)
        {
            return new Regex("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$").IsMatch(email);
        }

        /// <summary>
        /// 将数组或列表用某个字符串连接起来，组成一个新的字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static string ToJoin(this IEnumerable<object> source, string separator)
        {
            return string.Join(separator, source);
        }

        /// <summary>
        /// 把对象类型转换为指定类型
        /// </summary>
        /// <param name="value"></param>
        /// <param name="conversionType"></param>
        /// <returns></returns>
        public static object? CastTo(this object value, Type conversionType)
        {
            if (value != null)
            {
                if (conversionType.IsNullableType())
                {
                    conversionType = conversionType.GetUnNullableType();
                }
                if (conversionType.IsEnum)
                {
                    if(Enum.TryParse(conversionType, value.ObjectToString(), out object? result))
                    {
                        return result;
                    }
                }
                if (conversionType == typeof(Guid))
                {
                    return value.ObjectToGuid();
                }
                return Convert.ChangeType(value, conversionType);
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 把对象类型转化为指定类型
        /// </summary>
        /// <typeparam name="T"> 动态类型 </typeparam>
        /// <param name="value"> 要转化的源对象 </param>
        /// <returns> 转化后的指定类型的对象，转化失败引发异常。 </returns>
        public static T? CastTo<T>(this object value)
        {
            if (value != null)
            {
                if (value.GetType() == typeof(T))
                {
                    return (T)value;
                }
                else
                {
                    var result = CastTo(value, typeof(T));
                    if (result != null)
                    {
                        return (T)result;
                    }
                }
            }
            return default(T);
        }

        /// <summary>
        /// 把对象类型转化为指定类型，转化失败时返回指定的默认值
        /// </summary>
        /// <typeparam name="T"> 动态类型 </typeparam>
        /// <param name="value"> 要转化的源对象 </param>
        /// <param name="defaultValue"> 转化失败返回的指定默认值 </param>
        /// <returns> 转化后的指定类型对象，转化失败时返回指定的默认值 </returns>
        public static T? CastTo<T>(this object value, T defaultValue)
        {
            try
            {
                return CastTo<T>(value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将对象保存为csv
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="csvFullName">文件名称</param>
        /// <param name="separator">分隔符，默认逗号</param>
        public static void SaveToCsv<T>(this IEnumerable<T> source, string csvFullName, string separator = ",")
        {
            if (source != null)
            {
                if (string.IsNullOrEmpty(separator))
                    separator = ",";
                var csv = string.Join(separator, source);
                using (var sw = new StreamWriter(csvFullName, false))
                {
                    sw.Write(csv);
                    sw.Close();
                }
            }
            else
            {
                throw new ArgumentNullException(nameof(source));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityType"></param>
        /// <param name="interfaceType"></param>
        /// <returns></returns>
        public static bool IsImplement(this Type entityType, Type interfaceType)
        {
            return /*entityType.IsClass && !entityType.IsAbstract &&*/ entityType.GetTypeInfo().GetInterfaces().Any(t => t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == interfaceType);
        }

        /// <summary>
        /// 将对象转为DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this List<T> source)
        {
            using (DataTable dtReturn = new DataTable())
            {
                if (source != null)
                { 
                    if (source.Count > 0)
                    {
                        var firstData = source[0];
                        if (firstData != null)
                        {
                            dtReturn.TableName = firstData.GetType().Name; // 表名赋值
                            PropertyInfo[] propertys = firstData.GetType().GetProperties();
                            if (source.Count > 0)
                            {
                                foreach (PropertyInfo pi in propertys)
                                {
                                    Type colType = pi.PropertyType;
                                    if (colType.IsGenericType && colType.GetGenericTypeDefinition() == typeof(Nullable<>))
                                    {
                                        colType = colType.GetGenericArguments()[0];
                                    }
                                    dtReturn.Columns.Add(pi.Name, colType);
                                }
                                for (int i = 0; i < source.Count; i++)
                                {
                                    ArrayList tempList = new();
                                    foreach (PropertyInfo pi in propertys)
                                    {
                                        var obj = pi.GetValue(source[i], null);
                                        tempList.Add(obj);
                                    }
                                    var array = tempList.ToArray();
                                    dtReturn.LoadDataRow(array, true);
                                }
                            }
                        }
                    }
                }
                return dtReturn;
            }
        }

        #region 时间戳与时间的转换
        /// <summary>
        /// 
        /// </summary>
        private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        /// <summary>
        /// 将时间转为10位和13位时间戳
        /// </summary>
        /// <param name="date">时间</param>
        /// <param name="bflag">为真时获取10位时间戳,为假时获取13位时间戳.bool bflag = true</param>
        /// <returns></returns>
        public static long DateTimeToUnixTimeStamp(this DateTime date, bool bflag = true)
        {
            var utcTime = date.ToUniversalTime();
            var elapsedTime = utcTime - UnixEpoch;
            if (bflag)
            {
                return elapsedTime.TotalSeconds.ObjectToLong();
            }
            else
            {
                return elapsedTime.TotalMilliseconds.ObjectToLong();
            }
        }
        /// <summary>
        /// 将10位和13位时间戳转为时间
        /// </summary>
        /// <param name="unixTime">10位或13位时间戳</param>
        /// <returns></returns>
        public static DateTime UnixTimeStampToDateTime(string unixTime)
        {
            DateTime utcTime;
            long lTime = unixTime.ObjectToLong();
            if (unixTime.Length == 10)//判断是10位
            {
                utcTime = UnixEpoch.AddSeconds(lTime);
            }
            else if (unixTime.Length == 13)//判断是13位
            {
                utcTime = UnixEpoch.AddMilliseconds(lTime);
            }
            else
            {
                utcTime = UnixEpoch;
            }
            return utcTime.ToLocalTime(); ;

        }
        #endregion 时间戳与时间的转换
    }
}
